package com.jiajia.study.nio;


import java.nio.ByteBuffer;

/**
 *
 * NIO demo
 *
 * 一 缓冲区（buffer），在Java NIO 中负责数据的存储，缓冲区就是数组，用户存储不同数据类型的数据
 * 根据不同的数据类型（boolean)除外,提供了相应类型的缓冲区：
 *      ByteBuffer
 *      CharBuffer
 *      ShortBuffer
 *      IntegerBuffer
 *      LongBuffer
 *      FloatBuffer
 *      DoubleBuffer
 *
 *      上面缓冲区的管理方式基本上都是一致的，通过 allocate()获取缓冲区
 *
 * 二 缓冲区存取数据的两个核心的方法：
 *      put(): 存入数据到缓冲区中
 *      get(): 获取缓冲区的数据
 *
 * 三 缓冲区的四个核心属性：
 *
 *      capacity : 容量，表示缓冲区中最大存储数据的容量，一旦声明不能改变
 *      limit    : 界限，表示缓冲中可以操作数据的大小（limit后面的数据就不能在进行读写了）
 *      position : 位置，表示欢喜红区中正在操作数据的位置
 *      mark     : 标记， 表示记录当前position的位置，可以通过reset()恢复到mark的位置
 *
 *
 *      0 <= mark <= position <= limit <= capacity
 *
 * 四 直接缓冲区与非直接缓冲区：
 *
 *      非直接缓冲区  ：通过allocate() 方法分配缓冲区，将缓冲区建立在JVM中，
 *      直接缓冲区   : 通过allocateDirect() 方法直接分配缓冲区，将缓冲区建立在物理内存中，可以提高效率
 *
 *
 *
 * @author : zjj
 * @date : 2021-04-20 15:55
 */
public class Client {

    public static void main(String[] args) {
        testParam();
    }

    /**
     * 缓冲区获取
     */
    private static void test(){
        // 非直接缓冲区
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        // 直接缓冲区
        ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);

        System.out.println("是否是直接缓冲区：" + buffer.isDirect());

        System.out.println(
                "是否是直接缓冲区：" + directBuffer.isDirect()
        );

    }

    /**
     * 缓冲区几个关键的属性
     */
    private static void testParam(){
        String str = "abcde";

        // 分配一个指定大小的缓冲区
        ByteBuffer buffer = ByteBuffer.allocate(1024);

        System.out.println("================allocate()===================");

        System.out.println("position:" + buffer.position());
        System.out.println("limit:" + buffer.limit());
        System.out.println("capacity:" + buffer.capacity());
        System.out.println("mark:" + buffer.mark());

        // 往缓冲区中写入数据
        buffer.put(str.getBytes());

        System.out.println("==================put===================");

        System.out.println("position:" + buffer.position());
        System.out.println("limit:" + buffer.limit());
        System.out.println("capacity:" + buffer.capacity());
        System.out.println("mark:" + buffer.mark());

        // 切换读取数据的模式
        buffer.flip();
        System.out.println("===================flip()========================");

        System.out.println("position:" + buffer.position());
        System.out.println("limit:" + buffer.limit());
        System.out.println("capacity:" + buffer.capacity());
        System.out.println("mark:" + buffer.mark());


        // 利用get() 读取缓冲区中的数据
        byte[] bytes = new byte[buffer.limit()];
        // 将数据读到 bytes数据中
        buffer.get(bytes);
        System.out.println(new String(bytes,0,bytes.length));

        System.out.println("===================get()========================");

        System.out.println("position:" + buffer.position());
        System.out.println("limit:" + buffer.limit());
        System.out.println("capacity:" + buffer.capacity());
        System.out.println("mark:" + buffer.mark());

        // 可重复读 : rewind
        buffer.rewind();

        System.out.println("===================rewind()========================");

        System.out.println("position:" + buffer.position());
        System.out.println("limit:" + buffer.limit());
        System.out.println("capacity:" + buffer.capacity());
        System.out.println("mark:" + buffer.mark());

        System.out.println("====================mark()==============================");
        byte[] byteMark = new byte[buffer.limit()];
        buffer.get(byteMark,0,2);
        System.out.println(new String(byteMark,0,2));
        // 在 position 1 位置标记

        buffer.mark();
        buffer.get(byteMark,2,1);

        System.out.println(new String(byteMark,0,byteMark.length));
        // 重新回到 mark的位置
        buffer.reset();
        System.out.println("buffer position:"  + buffer.position());
        buffer.get(byteMark,buffer.position(),2);

        System.out.println(new String(byteMark,0,byteMark.length));
        System.out.println("buffer mark" + buffer.mark());

        // 清空缓冲区，但是缓冲区的数据依旧存在，处于‘被遗忘’状态
        buffer.clear();
        System.out.println("===================clear()========================");

        System.out.println("position:" + buffer.position());
        System.out.println("limit:" + buffer.limit());
        System.out.println("capacity:" + buffer.capacity());
        System.out.println("mark:" + buffer.mark());

        System.out.println((char) buffer.get());




    }



}
